<?php


namespace App\Services;

use App\Consts\GlobalConst;
use App\Consts\GlobalCounterConst;
use App\Consts\GlobalNoteConst;
use App\Events\CacheCounterEvent;
use App\Models\Cache\Cache;
use App\Models\Cache\CacheKey;
use App\Models\IndexNote;

class CounterService extends BaseService
{
    /**
     * 更新用户计数
     * @param $userId
     * @param string|array $countKeys
     * @param int $trend
     * @param bool $incrementUpdate
     * @return bool
     */
    public function editUserCount($userId, $countKeys, $trend = GlobalCounterConst::INCREASE, $incrementUpdate = true)
    {
        CacheCounterEvent::dispatch([
            'key_params' => ['user_id' => $userId],
            'cache_key' => CacheKey::COUNTER_USER,
            'values' => $countKeys,
            'trend' => $trend,
            'is_increment_update' => $incrementUpdate,
        ]);

        return true;
    }

    /**
     * 更新用户计数
     * @param $userId
     * @param string|array $countKeys
     * @param int $trend
     * @param bool $incrementUpdate
     * @return bool
     */
    public function editTargetCountByTargetType($targetId, $targetType, $countKeys, $trend = GlobalCounterConst::INCREASE, $incrementUpdate = true)
    {
        $data = [];
        if ($targetType == GlobalConst::TARGET_TYPE_ARTICLE) {
            $data = [
                'key_params' => ['article_id' => $targetId],
                'cache_key' => CacheKey::COUNTER_ARTICLE,
                'values' => $countKeys,
                'trend' => $trend,
                'is_increment_update' => $incrementUpdate,
            ];
        }

        if ($targetType == GlobalConst::TARGET_TYPE_NOTE) {
            $data = [
                'key_params' => ['note_id' => $targetId],
                'cache_key' => CacheKey::COUNTER_NOTE,
                'values' => $countKeys,
                'trend' => $trend,
                'is_increment_update' => $incrementUpdate,
            ];
        }

        if ($targetType == GlobalConst::TARGET_TYPE_DYNAMIC) {
            $data = [
                'key_params' => ['dynamic_id' => $targetId],
                'cache_key' => CacheKey::COUNTER_DYNAMIC,
                'values' => $countKeys,
                'trend' => $trend,
                'is_increment_update' => $incrementUpdate,
            ];
        }

        if (!$data) {
            return false;
        }

        CacheCounterEvent::dispatch($data);

        return true;
    }

    /**
     * @param string $cacheKey
     * @param array|string $countArr [要获取的计数]
     * @return array
     */
    public function getTargetCount($cacheKey, $countArr, $keyParams = [])
    {
        $cacheData = Cache::getInstance($keyParams)->hGetAll($cacheKey);
        $result = [];

        if (!$cacheData) {
            foreach ($countArr as $countName) {
                $result[$countName] = 0;
            }
            return $result;
        }
        $selfNote = 0;
        $publicNote = 0;
        $haveNote = false;
        foreach ($countArr as $countName) {
            if ($countName == 'note') {
                $selfNote = $cacheData[GlobalCounterConst::COUNT_SELF_NOTE] ?? 0;
                $publicNote = $cacheData[GlobalCounterConst::COUNT_PUBLIC_NOTE] ?? 0;
                $haveNote = true;
            } else if ($countName == GlobalCounterConst::COUNT_COLLECT) {
                $fakeCollect = $cacheData[GlobalCounterConst::FAKE_COLLECT] ?? 0;
                $countNum = $cacheData[$countName] ?? 0;
                $result[$countName] = $countNum + $fakeCollect;
            } else if ($countName == GlobalCounterConst::COUNT_LIKE) {
                $fakeLike = $cacheData[GlobalCounterConst::FAKE_LIKE] ?? 0;
                $countNum = $cacheData[$countName] ?? 0;
                $result[$countName] = $countNum + $fakeLike;
            } else if ($countName == GlobalCounterConst::COUNT_USER_RECOMMEND) {
                $fakeLike = $cacheData[GlobalCounterConst::FAKE_RECOMMEND] ?? 0;
                $countNum = $cacheData[$countName] ?? 0;
                $result[$countName] = $countNum + $fakeLike;
            } else if ($countName == GlobalCounterConst::COUNT_HOT) {
                $fakeHot = $cacheData[GlobalCounterConst::FAKE_HOT] ?? 0;
                $countNum = $cacheData[$countName] ?? 0;
                $result[$countName] = $countNum + $fakeHot;
            } else {
                if ($countName == GlobalCounterConst::COUNT_SELF_NOTE) {
                    $selfNote = $cacheData[GlobalCounterConst::COUNT_SELF_NOTE] ?? 0;
                    $haveNote = true;
                } else if ($countName == GlobalCounterConst::COUNT_PUBLIC_NOTE) {
                    $publicNote = $cacheData[GlobalCounterConst::COUNT_PUBLIC_NOTE] ?? 0;
                    $haveNote = true;
                } else {
                    $countNum = $cacheData[$countName] ?? 0;
                    $result[$countName] = $countNum;
                }
            }
        }
        if ($haveNote) {
            $result['note'] = $selfNote + $publicNote;
        }

        $data = [];
        foreach ($result as $key => $value) {
            $data[$key] = $value < 0 ? 0 : $value;
        }
        return $data;
    }

    public function getArticleCount($articleId, $currentUserId, $countArr)
    {
        $result = $this->getTargetCount(CacheKey::COUNTER_ARTICLE, $countArr, [
            'article_id' => $articleId,
        ]);
        if (in_array('note', $countArr)) {
            $result['note'] = $this->getArticleNoteCount($articleId, $currentUserId);
        }

        return $result;
    }

    public function getArticleNoteCount($articleId, $currentUserId)
    {
        $cacheData = Cache::getInstance([
            'article_id' => $articleId,
        ])->hGetAll(CacheKey::COUNTER_ARTICLE);
        if (!$cacheData || !array_key_exists(GlobalCounterConst::COUNT_PUBLIC_NOTE, $cacheData)) {
            return 0;
        }

        $articlePublicNoteCount = $cacheData[GlobalCounterConst::COUNT_PUBLIC_NOTE];

        $selfNotes = IndexNote::getInstance()
            ->where('user_id', $currentUserId,)
            ->where('article_id', $articleId,)
            ->where('is_public', GlobalNoteConst::IS_NOT_PUBLIC,)
            ->where('is_deleted', GlobalConst::IS_NOT_DELETE)
            ->get();

        return $articlePublicNoteCount + count($selfNotes);
    }
}
